#ifndef ISINGLETON_H
#define ISINGLETON_H

#define DECLARE_SINGLETON( _class ) friend class ISingleton< _class >

//**************************
//Pattern singleton
//**************************
template < class T >
class ISingleton
{
protected:
	/**
	 * @fn		ISingleton()
	 * @brief 	Default constructor
	 */
				ISingleton()	{}
	/**
	 * @fn		~CSingleton()
	 * @brief 	Destructor
	 */
	virtual 	~ISingleton()	{}
	
	static T*	s_pInstance;		/// Unique instance of the singleton
	
public:
	/**
	 * @fn		CreateInstance()
	 * @brief 	Create (if needed) the instance
	 */
	static void		CreateInstance()
	{
		if ( !s_pInstance )
			s_pInstance = new T();
	}
	
	/**
	 * @fn		DestroyInstance()
	 * @brief 	Destroy the instance
	 */
	static void		DestroyInstance()
	{
		if( s_pInstance )
			delete s_pInstance;
		s_pInstance = NULL;
	}
	
	/**
	 * @fn		GetInstancePtr()
	 * @brief 	Get the pointer on the instance
	 * @return	The pointer on the instance
	 */
	static T*		GetInstancePtr()
	{
		CreateInstance();
		
		return s_pInstance;
	}
	
	/**
	 * @fn		GetInstanceRef()
	 * @brief 	Get the reference on the instance
	 * @return	The reference on the instance
	 */
	 static T&		GetInstanceRef()
	{
		CreateInstance();
		
		return *s_pInstance;
	}
};

template < class T > T* ISingleton<T>::s_pInstance = NULL;

#endif